import dayjs, { Dayjs } from 'dayjs'
import { Ref, ref, computed, onMounted, watch } from 'vue'
import { fetchTopics, submitTopics } from '@evaluation-common/api'

export function delay(time: number) {
  let resolve: (value: unknown) => void

  const promise = new Promise((res) => (resolve = res))

  setTimeout(() => resolve(null), time)

  return promise
}

export function useItem({
  answerList,
  curIndex,
  isCompleted,
  projectId,
  handleSubmit,
  show,
}: {
  answerList: Ref<any[]>
  curIndex: Ref<number>
  isCompleted: Ref<boolean>
  projectId: Ref<string>
  handleSubmit: () => void
  show: Ref<boolean>
}) {
  return {
    getActive(item: any) {
      const answer = answerList.value[curIndex.value]
      if (!answer) return false
      return answer.subjectAnswerNo === item.subjectAnswerNo
    },
    onItemClick(item: any, gauge: any) {
      const isUpdate = curIndex.value < answerList.value.length

      const isAdd = !isUpdate

      const { subjectAnswerNo, sourceSubjectAnswerId, score, answer } = item

      const {
        adds,
        projectGaugeId,
        projectGaugeSubjectId,
        sourceProjectId,
        sourceSubjectId,
        subjecName,
        subjectNo,
        subjectType,
        tenantId,
        fixedType,
      } = gauge

      const allAnswer = (adds as any[]).map(({ answer }) => answer).join('|')

      const obj = {
        selectAnswer: answer,
        selectScore: score,
        sourceProjectId,
        gaugeId: sourceProjectId,
        sourceSubjectAnswerId,
        sourceSubjectId,
        subject: subjecName,
        subjectNo,
        subjectType,
        tenantId,
        userProjectGaugeId: projectGaugeId,
        score,
        projectId: projectId.value,
        projectGaugeSubjectId,
        projectGaugeId,
        answer,
        fixedType,
        allAnswer,
        subjectAnswerNo,
      }

      if (isAdd) {
        answerList.value.push(obj)
      }

      if (isUpdate) {
        answerList.value[curIndex.value] = obj
      }

      if (isCompleted.value) {
        // handleSubmit()
        show.value = true
        return
      }

      //   curIndex.value++
    },
  }
}

export function useTopics(projectId: Ref<string>) {
  const topicList = ref<any[]>([])

  const curIndex = ref(0)

  const curTopic = computed(() => topicList.value[curIndex.value])

  const options = computed(() => curTopic.value?.adds || [])

  const isCompleted = computed(
    () => curIndex.value >= topicList.value.length - 1
  )

  const getTopics = async () => {
    const params = {
      projectId: projectId.value,
    }

    const { data } = await fetchTopics(params)

    topicList.value = data.data
  }

  onMounted(() => {
    getTopics()
  })

  return {
    curIndex,
    curTopic,
    options,
    topicList,
    isCompleted,
    getTopics,
  }
}

export function useSubmit({
  answerList,
  projectId,
  userInfo,
  handleAfterSubmit,
  Dialog,
}: {
  answerList: Ref<any[]>
  projectId: Ref<string>
  userInfo: Ref<any>
  handleAfterSubmit?: (data: any) => void
  Dialog: any
}) {
  const { startTime, endTime, duration, getTime } = useTime()

  return {
    handleSubmit() {
      return Dialog.confirm({
        title: '恭喜你,完成所有问题,',
        message: '是否提交结果?',
        cancelButtonText: '返回修改',
        confirmButtonText: '确认提交',
        async beforeClose(action: string) {
          if (action != 'confirm') {
            return true
          }

          getTime()
          const datas: any[] = answerList.value
          const { gradeId, classNo, sexName, tenantName, account } =
            userInfo.value

          const userProjectGaugeEntity = {
            projectId: projectId.value,
            startTime: startTime.value.format('YYYY-MM-DD HH:mm:ss'),
            endTime: endTime.value.format('YYYY-MM-DD HH:mm:ss'),
            duration: duration.value,
            gradeId,
            classNo,
            sex: sexName,
            schoolName: tenantName,
            userName: account,
          }

          try {
            const { data } = await submitTopics({
              datas,
              userProjectGaugeEntity,
            })
            handleAfterSubmit?.(data)
          } catch (error) {
            console.error(error)
            return true
          }

          return true
        },
      })
    },
  }
}

export function useTime() {
  const startTime = ref<Dayjs>(dayjs())
  const endTime = ref<Dayjs>(dayjs())

  const duration = computed(() => endTime.value.diff(startTime.value, 's'))

  onMounted(() => {
    startTime.value = dayjs()
  })

  return {
    startTime,
    duration,
    endTime,
    getTime() {
      endTime.value = dayjs()
    },
  }
}

const defaultDelayTime = 2000

export function useDisabledDuration({
  curIndex,
  delayTime = defaultDelayTime,
}: {
  curIndex: Ref<number>
  delayTime?: number
}) {
  const disabled = ref(true)

  watch(
    curIndex,
    async () => {
      disabled.value = true
      await delay(delayTime)
      disabled.value = false
    },
    { immediate: true }
  )

  return disabled
}

export function useJump({
  curIndex,
  answerList,
  isCompleted,
  handleSubmit,
  Toast,
  show,
}: {
  curIndex: Ref<number>
  answerList: Ref<any[]>
  isCompleted: Ref<boolean>
  handleSubmit: () => void
  Toast: any
  show: Ref<boolean>
}) {
  const preVisible = computed(() => curIndex.value > 0)

  const nextVisible = computed(() => curIndex.value < answerList.value.length)

  const nextDisabled = useDisabledDuration({ curIndex })

  return {
    preVisible,
    nextVisible,
    nextDisabled,
    handleSwipe({ deltaX }: any) {
      const isLeft = deltaX > 0

      const isRight = !isLeft

      if (isLeft && preVisible.value) {
        curIndex.value--
      }

      if (isRight && nextVisible.value) {
        curIndex.value++
      }
    },
    handleClickPre() {
      if (!preVisible.value) {
        Toast('不能再往前了!')

        return
      }
      curIndex.value--
    },
    handleClickNext() {
      if (!nextVisible.value) {
        Toast('请先选择答案!')
        return
      }

      if (isCompleted.value) {
        // handleSubmit()
        show.value = true
        return
      }

      curIndex.value++
    },
  }
}
